/**
 * 日期时间操作
 */
class DateTimeFn {

    /**
     * @desc   格式化时间
     * @param  {String} time 时间
     * @param  {String} cFormat 格式
     * @return {String} 字符串
     * @example formatTime('2018-1-29', '{y}/{m}/{d} {h}:{i}:{s}') // -> 2018/01/29 00:00:00
     */
    static formatTime(time, cFormat) {
        if (arguments.length === 0) return null;
        if ((time + '').length === 10) {
            time = +time * 1000
        }

        let format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}', date;
        if (typeof time === 'object') {
            date = time
        } else {
            date = new Date(time)
        }

        let formatObj = {
            y: date.getFullYear(),
            m: date.getMonth() + 1,
            d: date.getDate(),
            h: date.getHours(),
            i: date.getMinutes(),
            s: date.getSeconds(),
            a: date.getDay()
        };
        return format.replace(/{([ymdhisa])+}/g, (result, key) => {
            let value = formatObj[key];
            if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1];
            if (result.length > 0 && value < 10) {
                value = '0' + value
            }
            return value || 0
        });
    }


    /**
     * @desc  ${startTime - endTime}的剩余时间,startTime大于endTime时，均返回0
     * @param { Date | String } startTime
     * @param { Date | String } endTime
     * @returns { Object } { d, h, m, s } 天 时 分 秒
     */
    static timeLeft(startTime, endTime) {
        if (!startTime || !endTime) {
            return null
        }
        let startDate, endDate;
        if (startTime instanceof Date) {
            startDate = startTime;
        } else {
            startDate = new Date(startTime.replace(/-/g, '/')) //开始时间
        }
        if (endTime instanceof Date) {
            endDate = endTime;
        } else {
            endDate = new Date(endTime.replace(/-/g, '/')) //结束时间
        }
        let t = endDate.getTime() - startDate.getTime();
        let d = 0,
            h = 0,
            m = 0,
            s = 0;
        if (t >= 0) {
            d = Math.floor(t / 1000 / 3600 / 24);
            h = Math.floor(t / 1000 / 60 / 60 % 24);
            m = Math.floor(t / 1000 / 60 % 60);
            s = Math.floor(t / 1000 % 60)
        }
        return {d, h, m, s}
    }

    /**
     * @desc   判断是否为同一天
     * @param  {Date} date1
     * @param  {Date} date2 可选／默认值：当天
     * @return {Boolean}
     */
    static isSameDay(date1, date2) {
        if (!date2) {
            date2 = new Date();
        }
        let date1_year = date1.getFullYear(),
            date1_month = date1.getMonth() + 1,
            date1_date = date1.getDate();
        let date2_year = date2.getFullYear(),
            date2_month = date2.getMonth() + 1,
            date2_date = date2.getDate();

        return date1_date === date2_date && date1_month === date2_month && date1_year === date2_year;
    }

    /**
     * @desc 是否为闰年
     * @param {Number} year
     * @returns {Boolean}
     */
    static isLeapYear(year) {
        return 0 === year % 4 && (year % 100 !== 0 || year % 400 === 0);
    }

    /**
     * @desc   格式化现在距${endTime}的剩余时间
     * @param  {Date} endTime
     * @return {String}
     */
    static formatRemainTime(endTime) {
        let startDate = new Date(); //开始时间
        let endDate = new Date(endTime); //结束时间
        let t = endDate.getTime() - startDate.getTime(); //时间差
        let d = 0,
            h = 0,
            m = 0,
            s = 0;
        if (t >= 0) {
            d = Math.floor(t / 1000 / 3600 / 24);
            h = Math.floor(t / 1000 / 60 / 60 % 24);
            m = Math.floor(t / 1000 / 60 % 60);
            s = Math.floor(t / 1000 % 60);
        }
        return d + "天 " + h + "小时 " + m + "分钟 " + s + "秒";
    }

    /**
     * @desc   格式化${startTime}距现在的已过时间
     * @param  {Date} startTime
     * @return {String}
     */
    static formatPassTime(startTime) {
        let currentTime = Date.parse(new Date());
        let time = currentTime - startTime;
        let day = parseInt(time / (1000 * 60 * 60 * 24));
        let hour = parseInt(time / (1000 * 60 * 60));
        let min = parseInt(time / (1000 * 60));
        let month = parseInt(day / 30);
        let year = parseInt(month / 12);
        if (year) return year + "年前";
        if (month) return month + "个月前";
        if (day) return day + "天前";
        if (hour) return hour + "小时前";
        if (min) return min + "分钟前";
        else return '刚刚'
    }

    /**
     * 返回指定长度的月份集合
     *
     * @param  {String} time 时间
     * @param  {Number} len 长度
     * @param  {Number} direction 方向：  1: 前几个月;  2: 后几个月;  3:前后几个月  默认 3
     * @return {Array} 数组
     *
     * @example   getMonths('2018-1-29', 6, 1)  // ->  ["2018-1", "2017-12", "2017-11", "2017-10", "2017-9", "2017-8", "2017-7"]
     */
    static getMonths(time, len, direction) {
        let mm = new Date(time).getMonth() + 1;
        let yy = new Date(time).getFullYear();
        let index = mm;
        direction = isNaN(direction) ? 3 : direction;

        let cutMonth = function (index) {
            let arr;
            if (direction === 1) {
                arr = formatPre(index).reverse()
            } else if (direction === 2) {
                arr = formatNext(index)
            } else {
                arr = formatPre(index).reverse().slice(len / 2).concat(formatNext(index).slice(1, len / 2 + 1))
            }
            return arr.sort(function (t1, t2) {
                return new Date(t1).getTime() - new Date(t2).getTime()
            })
        };

        let formatPre = function (index) {
            let currNum = index,
                preNum = 0,
                currArr = [],
                preArr = [];
            if (index - len < 0) {
                preNum = len - currNum
            }
            for (let i = 0; i < currNum; i++) {
                currArr.push([yy + '-' + (currNum - i)])
            }
            for (let i = 1; i <= preNum; i++) {
                preArr.push([(yy - Math.ceil(i / 12)) + '-' + (12 - (i - 1) % 12)])
            }
            return currArr.concat(preArr)
        };

        let formatNext = function (index) {
            let currNum = 12 - index,
                nextNum = 0,
                currArr = [],
                nextArr = [];
            if (len - currNum > 0) {
                nextNum = len - currNum
            }
            for (let i = 0; i <= currNum; i++) {
                currArr.push([yy + '-' + (index + i)])
            }
            for (let i = 1; i < nextNum; i++) {
                nextArr.push([(yy + Math.ceil(i / 12)) + '-' + (i % 13 === 0 ? 1 : i % 13)])
            }
            return currArr.concat(nextArr)
        };
        return cutMonth(index)
    }


    /**
     * 返回指定长度的天数集合
     *
     * @param  {String} time 时间
     * @param  {Number} len 长度
     * @param  {Number} direction 方向：  1: 前几个月;  2: 后几个月;  3:前后几个月  默认 3
     * @return {Array} 数组
     *
     * @example date.getDays('2018-1-29', 6) // -> ["2018-1-26", "2018-1-27", "2018-1-28", "2018-1-29", "2018-1-30", "2018-1-31", "2018-2-1"]
     */
    static getDays(time, len, direction) {
        let tt = new Date(time);
        let getDay = function (day) {
            let t = new Date(time);
            t.setDate(t.getDate() + day);
            let m = t.getMonth() + 1;
            return t.getFullYear() + '-' + m + '-' + t.getDate()
        };
        let arr = [];
        if (direction === 1) {
            for (let i = 1; i <= len; i++) {
                arr.unshift(getDay(-i))
            }
        } else if (direction === 2) {
            for (let i = 1; i <= len; i++) {
                arr.push(getDay(i))
            }
        } else {
            for (let i = 1; i <= len; i++) {
                arr.unshift(getDay(-i))
            }
            arr.push(tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate());
            for (let i = 1; i <= len; i++) {
                arr.push(getDay(i))
            }
        }
        return direction === 1 ? arr.concat([tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()]) :
            direction === 2 ? [tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()].concat(arr) : arr
    }


    /**
     * 格式化HMS
     * @param  {number} s 秒数
     * @return {String} 字符串
     * @example formatHMS(3610) // -> 1h0m10s
     */
    static formatHMS(s) {
        let str = '';
        if (s > 3600) {
            str = Math.floor(s / 3600) + 'h' + Math.floor(s % 3600 / 60) + 'm' + s % 60 + 's'
        } else if (s > 60) {
            str = Math.floor(s / 60) + 'm' + s % 60 + 's'
        } else {
            str = s % 60 + 's'
        }
        return str
    }

    /**
     * 某月有多少天
     *
     * @param  {String} time 时间
     * @return {Number} 天数
     */
    static getMonthOfDay(time) {
        let date = new Date(time);
        let year = date.getFullYear();
        let mouth = date.getMonth() + 1;
        let days;

        //当月份为二月时，根据闰年还是非闰年判断天数
        if (mouth === 2) {
            days = (year % 4 === 0 && year % 100 === 0 && year % 400 === 0) || (year % 4 === 0 && year % 100 !== 0) ? 28 : 29
        } else if (mouth === 1 || mouth === 3 || mouth === 5 || mouth === 7 || mouth === 8 || mouth === 10 || mouth === 12) {
            //月份为：1,3,5,7,8,10,12 时，为大月.则天数为31；
            days = 31
        } else {
            //其他月份，天数为：30.
            days = 30
        }
        return days
    }

}

module.exports = DateTimeFn;